<template>
  <div class="p-5">
    <div class="flex gap-2.5 mb-4">
      <el-button type="primary" @click="handleAdd" class="rounded-none"> 新增配置 </el-button>
    </div>
    <el-card>
      <template #header>
        <div class="flex justify-between items-center">
          <span>系统配置管理</span>
          <div class="flex items-center w-[240px] mr-2.5">
            <el-input v-model="searchKey" placeholder="搜索配置键或名称" size="small" :prefix-icon="Search" />
          </div>
        </div>
      </template>
      <el-table v-loading="loading" :data="filteredConfigs" style="width: 100%" border>
        <el-table-column prop="name" label="配置名称" min-width="160" />
        <el-table-column prop="key" label="配置键" min-width="180" />
        <el-table-column prop="description" label="描述" min-width="260">
          <template #default="scope: { row: ConfigItem }">
            <div
              class="whitespace-nowrap overflow-hidden text-ellipsis max-w-full"
              :title="scope.row.description || ''">
              {{ scope.row.description || '' }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="配置值" min-width="180">
          <template #default="scope: { row: ConfigItem }">
            <div v-if="editingRow === scope.row.id">
              <el-input
                v-if="scope.row.type === 'string' || scope.row.type === 'number'"
                v-model="editForm.value"
                placeholder="请输入配置值"
                :type="scope.row.type === 'number' ? 'number' : 'text'" />
              <el-switch v-else-if="scope.row.type === 'boolean'" v-model="editForm.value" />
              <el-select
                v-else-if="scope.row.type === 'select' && scope.row.options"
                v-model="editForm.value"
                placeholder="请选择">
                <el-option
                  v-for="option in scope.row.options"
                  :key="option.value"
                  :label="option.label"
                  :value="option.value" />
              </el-select>
              <el-input v-else v-model="editForm.value" type="textarea" placeholder="请输入配置值" />
            </div>
            <div v-else>
              <template v-if="scope.row.type === 'boolean'">
                <span :class="scope.row.value === 'true' ? 'text-green-500' : 'text-red-500'">{{
                  scope.row.value === 'true' ? '启用' : '禁用'
                }}</span>
              </template>
              <template v-else-if="scope.row.type === 'json' && scope.row.value">
                <el-popover
                  placement="top"
                  :width="140"
                  trigger="hover"
                  contentStyle="max-height: 400px; overflow: auto;">
                  <template #reference>
                    <span
                      class="text-blue-500 dark:text-blue-400 cursor-pointer bg-blue-50 dark:bg-gray-700 px-2 py-1 rounded"
                      >查看JSON</span
                    >
                  </template>
                  <div class="bg-gray-50 dark:bg-gray-800 rounded-md p-3 max-w-full overflow-x-auto text-sm">
                    <pre
                      class="text-[#606266] dark:text-gray-200 m-0 whitespace-pre-wrap break-words"
                      v-html="formatJson(String(scope.row.value))"></pre>
                  </div>
                </el-popover>
              </template>
              <template v-else-if="scope.row.type === 'select' && scope.row.options">
                {{ scope.row.options.find((option) => option.value === scope.row.value)?.label || scope.row.value }}
              </template>
              <template v-else>
                {{ scope.row.value }}
              </template>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="type" label="类型" min-width="80">
          <template #default="{ row }">
            <el-tag :type="getTypeTagType(row.type)">{{ getTypeName(row.type) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="系统配置" min-width="80">
          <template #default="{ row }">
            <el-tag :type="row.system ? 'danger' : 'default'">{{ row.system ? '是' : '否' }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" min-width="160" fixed="right">
          <template #default="{ row }">
            <div v-if="editingRow === row.id">
              <el-button type="primary" size="small" @click="handleSave(row.id)" :loading="savingId === row.id">
                保存
              </el-button>
              <el-button type="danger" size="small" @click="cancelEdit">取消</el-button>
            </div>
            <div v-else>
              <el-button type="primary" size="small" @click="handleEdit(row)" :disabled="!!editingRow">
                编辑
              </el-button>
              <el-button
                v-if="!row.system"
                type="danger"
                size="small"
                @click="handleDelete(row.id)"
                :disabled="!!editingRow">
                删除
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页组件 -->
      <div class="flex justify-end mt-4">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange" />
      </div>
    </el-card>

    <!-- 新增配置对话框 -->
    <el-dialog v-model="adding" title="新增配置" width="600px">
      <el-form ref="addFormRef" :model="addForm" :rules="addFormRules" label-width="100px">
        <el-form-item label="配置名称" prop="name">
          <el-input v-model="addForm.name" placeholder="请输入配置名称" />
        </el-form-item>
        <el-form-item label="配置键" prop="key">
          <el-input v-model="addForm.key" placeholder="请输入配置键" />
        </el-form-item>
        <el-form-item label="配置值" prop="value">
          <el-input v-if="addForm.type === 'string'" v-model="addForm.value" placeholder="请输入配置值" type="text" />
          <el-switch v-else-if="addForm.type === 'boolean'" v-model="addForm.value" />
          <el-input
            v-else-if="addForm.type === 'json'"
            v-model="addForm.value"
            type="textarea"
            placeholder="请输入JSON字符串" />
          <el-input
            v-else-if="addForm.type === 'number'"
            v-model.number="addForm.value"
            type="number"
            placeholder="请输入数字" />
          <el-input v-else v-model="addForm.value" type="textarea" placeholder="请输入配置值" />
        </el-form-item>
        <el-form-item label="类型" prop="type">
          <el-select v-model="addForm.type" placeholder="请选择类型">
            <el-option label="字符串" value="string" />
            <el-option label="布尔值" value="boolean" />
            <el-option label="数字" value="number" />
            <el-option label="下拉选择" value="select" />
            <el-option label="JSON" value="json" />
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input v-model="addForm.description" type="textarea" placeholder="请输入描述" />
        </el-form-item>
        <el-form-item v-if="addForm.type === 'select'" label="选项列表" prop="options">
          <el-input
            v-model="addForm.options"
            type="textarea"
            placeholder="请输入选项列表，格式为：选项1:值1,选项2:值2" />
          <div class="text-xs text-gray-500 mt-1">提示：使用英文逗号分隔不同选项，冒号分隔选项标签和值</div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button type="danger" @click="cancelAdd">取消</el-button>
        <el-button type="primary" @click="handleAddSave">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElForm, ElMessageBox } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import { getAllConfigs, createConfig, updateConfigByKey } from '@/api/config'
import request from '@/utils/request'
import { HttpStatus, type ConfigItem } from '@/api/types'

defineOptions({ name: 'config' })

// 状态定义
const configs = ref<ConfigItem[]>([])
const loading = ref(false)
const searchKey = ref('')
// 分页相关状态
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const editingRow = ref<number | null>(null)
const editForm = ref<Partial<ConfigItem>>({})
const savingId = ref<number | null>(null)
// 新增配置相关状态
const adding = ref(false)
const addForm = ref<Partial<{ options: string | null } & ConfigItem>>({
  type: 'string',
  name: '',
  key: '',
  value: '',
  options: null,
})
const addFormRef = ref<InstanceType<typeof ElForm> | null>(null)

// 新增配置表单验证规则
const addFormRules = {
  name: [
    { required: true, message: '请输入配置名称', trigger: 'blur' },
    { max: 100, message: '配置名称不能超过100个字符', trigger: 'blur' },
  ],
  key: [
    { required: true, message: '请输入配置键', trigger: 'blur' },
    { pattern: /^[a-zA-Z0-9_\.]+$/, message: '配置键只能包含字母、数字、点和下划线', trigger: 'blur' },
    { max: 50, message: '配置键不能超过50个字符', trigger: 'blur' },
  ],
  value: [
    { required: true, message: '请输入配置值', trigger: 'blur' },
    {
      validator: (rule: any, value: string | null, callback: any) => {
        if (addForm.value?.type === 'json' && value) {
          try {
            JSON.parse(value)
            callback()
          } catch (e) {
            callback(new Error('请输入有效的JSON字符串'))
          }
        } else {
          callback()
        }
      },
      trigger: 'blur,change',
    },
  ],
  type: [{ required: true, message: '请选择配置类型', trigger: 'change' }],
  options: [
    {
      validator: (rule: any, value: string | null, callback: any) => {
        if (addForm.value?.type === 'select' && (!value || value.trim() === '')) {
          callback(new Error('请输入选项列表'))
        } else if (addForm.value?.type === 'select' && value) {
          // 验证选项格式
          const options = value.split(',')
          const valid = options.every((item) => {
            const parts = item.split(':')
            return parts.length === 2 && parts[0].trim() && parts[1].trim()
          })
          if (!valid) {
            callback(new Error('选项格式不正确，请使用","选项1":"值1,选项2:值2"格式'))
          } else {
            callback()
          }
        } else {
          callback()
        }
      },
      trigger: 'blur,change',
    },
  ],
}

// 筛选配置
const filteredConfigs = computed<ConfigItem[]>(() => {
  if (!searchKey.value) return configs.value

  const key = searchKey.value.toLowerCase()
  return configs.value.filter(
    (item) =>
      item.key.toLowerCase().includes(key) ||
      item.name.toLowerCase().includes(key) ||
      (item.description && item.description.toLowerCase().includes(key)),
  )
})

// 获取所有配置
const fetchConfigs = async () => {
  loading.value = true
  try {
    const res = await getAllConfigs(currentPage.value, pageSize.value)
    configs.value = res.data || []
    total.value = res.total || 0
  } catch (error) {
    ElMessage.error('获取配置失败')
    console.error(error)
  } finally {
    loading.value = false
  }
}

// 处理分页变更
const handleCurrentChange = (page: number) => {
  currentPage.value = page
  fetchConfigs()
}

// 处理每页条数变更
const handleSizeChange = (size: number) => {
  pageSize.value = size
  currentPage.value = 1
  fetchConfigs()
}

// 格式化JSON显示
const formatJson = (jsonString: string) => {
  try {
    const obj = JSON.parse(jsonString)

    // 递归函数处理JSON对象并添加样式
    const processValue = (value: any, indent: number = 0): string => {
      const indentStr = ' '.repeat(indent)

      if (value === null) {
        return `<span class="text-purple-600">null</span>`
      } else if (typeof value === 'boolean') {
        return `<span class="text-purple-600">${value}</span>`
      } else if (typeof value === 'number') {
        return `<span class="text-orange-600">${value}</span>`
      } else if (typeof value === 'string') {
        return `<span class="text-blue-600">"${value}"</span>`
      } else if (Array.isArray(value)) {
        if (value.length === 0) {
          return '[]'
        }

        const items = value
          .map((item, index) => {
            const isLast = index === value.length - 1
            return `${indentStr}  ${processValue(item, indent + 2)}${isLast ? '' : ','}`
          })
          .join('\n')

        return `[\n${items}\n${indentStr}]`
      } else if (typeof value === 'object') {
        const keys = Object.keys(value)
        if (keys.length === 0) {
          return '{}'
        }

        const items = keys
          .map((key, index) => {
            const isLast = index === keys.length - 1
            return `${indentStr}  <span class="text-green-600">"${key}"</span>: ${processValue(value[key], indent + 2)}${isLast ? '' : ','}`
          })
          .join('\n')

        return `{\n${items}\n${indentStr}}`
      } else {
        return String(value)
      }
    }

    // 生成带样式的JSON
    const highlightedJson = processValue(obj)

    return highlightedJson
  } catch (e) {
    return `<span class="text-red-500">Invalid JSON: ${jsonString}</span>`
  }
}

// 类型中文名称
const getTypeName = (type: string) => {
  const typeMap: Record<string, string> = {
    string: '字符串',
    boolean: '布尔',
    select: '选项',
    json: 'JSON',
    number: '数字',
  }
  return typeMap[type] || type
}

// 类型标签样式
const getTypeTagType = (type: string) => {
  const typeTagMap: Record<string, string> = {
    string: 'primary',
    boolean: 'success',
    select: 'warning',
    json: 'info',
    number: 'default',
  }
  return typeTagMap[type] || 'default'
}

// 处理编辑
const handleEdit = (row: ConfigItem) => {
  editingRow.value = row.id
  // 尝试解析JSON值
  try {
    if (row.type === 'json' && row.value) {
      editForm.value = {
        ...row,
        value: row.value,
      }
    } else if (row.type === 'boolean') {
      editForm.value = {
        ...row,
        value: row.value === 'true',
      }
    } else if (row.type === 'number') {
      editForm.value = {
        ...row,
        value: Number(row.value),
      }
    } else {
      editForm.value = { ...row }
    }
  } catch (e) {
    editForm.value = { ...row }
  }
}

// 取消编辑
const cancelEdit = () => {
  editingRow.value = null
  editForm.value = {}
}

// 处理保存
const handleSave = async (id: number) => {
  if (!editForm.value) return

  savingId.value = id
  try {
    // 处理值类型
    let value = editForm.value.value
    if (typeof value === 'boolean' || typeof value === 'number') {
      value = String(value)
    }
    // 使用updateConfigByKey接口更新配置
    const res = await updateConfigByKey(editForm.value.key as string, value, {
      name: editForm.value.name,
      description: editForm.value.description,
      type: editForm.value.type,
      options: editForm.value.options,
    })

    // 更新本地数据
    const index = configs.value.findIndex((item) => item.id === id)
    if (index !== -1) {
      if (res.data) configs.value[index] = res.data
    }

    ElMessage.success('保存成功')
    editingRow.value = null
  } catch (error) {
    ElMessage.error('保存失败')
    console.error(error)
  } finally {
    savingId.value = null
  }
}

// 打开新增对话框
const handleAdd = () => {
  addForm.value = { type: 'string' }
  adding.value = true
}

// 取消新增
const cancelAdd = () => {
  adding.value = false
  addForm.value = { type: 'string' }
  if (addFormRef.value) {
    addFormRef.value.resetFields()
  }
}

// 保存新增配置
const handleAddSave = async () => {
  if (!addFormRef.value) return
  // 验证表单
  await addFormRef.value.validate()
  // 处理值类型
  let value = addForm.value.value
  if (typeof value === 'object') {
    value = JSON.stringify(value)
  } else if (typeof value === 'boolean' || typeof value === 'number') {
    value = String(value)
  }

  // 处理选项列表
  let options = null
  if (addForm.value.type === 'select' && addForm.value.options) {
    // 解析选项字符串为数组
    options = addForm.value.options.split(',').map((item) => {
      const [label, val] = item.split(':', 2)
      return { label: label.trim(), value: val.trim() }
    })
    // 过滤无效选项
    options = options.filter((item) => item.label && item.value)
  }

  // 使用createConfig接口创建新配置
  const res = await createConfig(addForm.value.key as string, value, {
    name: addForm.value.name,
    description: addForm.value.description,
    type: addForm.value.type,
    options: options,
  })
  if (res.statusCode === HttpStatus.CREATED) {
    // 重新从服务器获取配置列表（带分页）
    await fetchConfigs()
    adding.value = false
    ElMessage.success('新增成功')
  } else {
    ElMessage.error(res.message)
  }
}

// 删除配置
const handleDelete = async (id: number) => {
  try {
    // 查找要删除的配置项
    const configItem = configs.value.find((item) => item.id === id)

    // 检查是否是系统配置
    if (configItem && configItem.system) {
      ElMessage.warning('系统配置无法删除')
      return
    }

    // 显示确认对话框
    await ElMessageBox.confirm('确定要删除该配置吗？', '删除确认', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })

    // 假设存在deleteConfig接口
    await request.delete({
      url: `/config/${id}`,
    })

    // 从本地数据删除
    configs.value = configs.value.filter((item) => item.id !== id)

    ElMessage.success('删除成功')
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
      console.error(error)
    }
  }
}

// 初始加载
onMounted(() => {
  fetchConfigs()
})
</script>

<style scoped></style>
